/*
 * ===================================================================
 *  
 *      Filename: util.h
 *
 *   Description: greate header file for the system, almost all of the 
 *                defination of the variables are created in this file.
 *
 *       Version:  1.0
 *        Create:  2010/07/13
 *
 *        Author:  Keven Zhu     kevenzhu@tencent.com
 *     Copyright:  Reserved by Tencent.com Co.ltd
 *   
 * ====================================================================
 */
#ifndef __HPLOG_UTIL__
#define __HPLOG_UTIL__
#include <sys/types.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/socket.h>


#define  __USE_GNU
#include <sched.h>
#include <pthread.h>

#include "list.h"

#define TRUE  1
#define FALSE 0
#define OK    1

#define likely(x)    __builtin_expect(!!(x),1)
#define unlikely(x)  __builtin_expect(!!(x),0)

#define SPORT         10514
#define CLIENT_PORT   41501
#define MNG_PORT      41502
#define CLT_MULT      41503
#define POLICY_MULT_GROUP    "224.0.0.218"

/*local socket file*/
#define LOCAL_SOCKET_FILE    "/tmp/hplogd.sock"

#define DEFAULT_LOG_PATH     "/data/kevenzhu/hplogd.log"
#define DEFAULT_COLOR_PATH   "/data/kevenzhu/color.log"
#define DEFAULT_POLICY_PATH  "/etc/hplogd.conf"

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*interface for the memory pool*/
extern int mem_pool_init(size_t max_elts);
extern void mem_pool_destroy();
extern char*   hplogd_malloc(size_t size);
extern void    hplogd_free(char* buf);

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*public structure*/
typedef struct thread_info_s thread_info_t;

struct thread_info_s
{
    pthread_t         thread;
    unsigned long cpu_affinity;
    unsigned long max_queue;
    unsigned long max_queue_mask;
    unsigned long enqueue_counter;
    unsigned long dequeue_counter;
    pthread_attr_t attr;
    void**        log_list;
};

/*static variable for the queue*/
#define MAX_LOG_SIZE         1024

#define MAX_MAIN_QUEUE       4096
#define MAX_MAIN_QUEUE_MASK  4095

#define MAX_WORK_QUEUE       512
#define MAX_WORK_MASK        511

#define HIGH_THRESHOLD_TRIGGER 50

/*return value indicate the queue status*/
enum queue_return
{
	LOW_THRESHOLD    = 1,
	NORMAL_THRESHOLD = 2,
	HIGH_THRESHOLD   = 3,
	URGENCY_THRESHOLD= 4
};

/*the processing result of the plugin*/
enum plugin_ret
{
    PR_ACCEPT = 1, /*the plugin has processed it,continue the next*/
    PR_STOP   = 2, /*it's enough for this plug, exit the loop*/
    PR_MAX    = PR_STOP
};

extern pthread_mutex_t counter_mutex;
extern struct list_head plugin_list;
extern int    enqueue(thread_info_t *pthread,void *data);
extern void*  dequeue(thread_info_t *pthread);
extern void   init_queue(thread_info_t *pthread, int max_queue);
extern void   finit_queue(thread_info_t *pthread);
extern inline int main_framer_process_pkt(char *msg); 
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*head file for the plugin operation*/

/*define the prototype for the callback function
 *please make sure all of the data are local,and
 *the callback function call run concurrently
 */
typedef int        init_plugin(int buffer_size, int buffer_counter); //init the buffer and lock
typedef int        finit_plugin();  //free the buffer and lock, the process_log must not be called anymore before call it
typedef enum plugin_ret callback_process_log(char* msg);
typedef char*      callback_plugin_name();
typedef int        callback_trylock();
typedef int        callback_lock();
typedef int        callback_unlock();
/*define prototype for the plugin,pc is short for plugin control*/
typedef struct pc_plugin_ops_
{
    struct list_head list;              /*NOT used*/
    callback_process_log *process_log;  /*main routine for processing the log*/
    callback_trylock     *trylock;      /*try to lock the buffer*/
    callback_lock        *lock;         /*lock the buffer*/
    callback_unlock      *unlock;       /*unlock the buffer*/
    callback_plugin_name *plugin_name;  /*get the name of the plugin*/               
    finit_plugin         *unload_plugin;/*unload the plugin*/
    int    identifier;                  /*index in the array*/
}pc_plugin_ops;

pc_plugin_ops *file_initialize_plugin(int buffer_size, int buffer_counter);
pc_plugin_ops *color_initialize_plugin(int buffer_size, int buffer_counter);

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*public macro*/
/**
 * container_of - cast a member of a structure out to the containing structure
 * @ptr:    the pointer to the member.
 * @type:  the type of the container struct this is embedded in.
 * @member:   the name of the member within the struct.
 *
 */
#define container_of(ptr, type, member) ({          \
            const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
            (type *)( (char *)__mptr - offsetof(type,member) );})



/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*interface for the policy*/
extern int init_tlogd_policy();
/*make sure it will be call before the main entry exiting*/
extern int finit_tlogd_policy();
/*only the ipv4 client is supported*/
extern int add_remote_client(uint addr);
extern int remove_remote_client(uint addr);

/*protocol for the reopen file(color/log),update policy file*/
/*|----------------------------------------------------------------
 *|action(byte)|lenth(byte)(optional)| msg body(file name)        |
 *|---------------------------------------------------------------|
 *|                    msg(file name)                             |
 *|---------------------------------------------------------------|
 *action:
 *0x01   update policy file
 *0x02   reopen log   file
 *0x03   reopen color file
 *0x04   accept the request
 *0x05   reject the request,if we reject the request, rejecting reason will be filled in the msg body
 */
#define UPDATE_POLICY_FILE     0x01
#define REOPEN_LOG_FILE        0x02
#define REOPEN_COLOR_FILE      0x03
#define ACCEPT_POLICY_REQUEST  0x04
#define REJECT_POLICY_REQUEST  0x05

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*interface for the main framer*/
extern int reopen_local_file(int file_type,int name_size,char *file_name);


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*interface for the protocol module*/
extern int init_protocol_udp();
extern int finit_protocol_udp();
extern int protocol_udp_join();
extern int init_protocol_tcp();
extern int finit_protocol_tcp();
extern int protocol_tcp_join();

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*send packet to the client using private protocol*/
/*|-------------------------------------------------------------------
 *|protocol(4bits)|version(4bits)|operation(byte)|file version(int)   |
 *|-------------------------------------------------------------------|
 *|protocol(4bits)|version(4bits)|operation(byte)|sequence(string)    |
 *|-------------------------------------------------------------------|
 *|length(4 bytes)|                      data                         |
 *|-------------------------------------------------------------------|
 *protocol
 0x01   color
 0x02   policy
 *version
 0x1
 *operation
 for color:                        for policy:
 0x01 enable  request              0x01 update request
 0x02 enable  reply                0x02 update accept
 0x03 disable request              0x03 update reject
 0x04 disable reply                0x04 update data
 0x05 request finish               0x05 update finish
 */
#define CS_PROTOCOL_POLICY       0x02
#define CS_PROTOCOL_COLOR        0x01
#define CS_VERSION     0x01
#define REQUEST_COLOR  0x01
#define ENABLE_COLOR_REQUEST     0x01
#define ENABLE_COLOR_REPLY       0x02
#define DISABLE_COLOR_REQUEST    0x01
#define DISABLE_COLOR_REPLY      0x02

#define REQUEST_POLICY 0x02
#define UPDATE_POLICY_REQUEST 0x01
#define UPDATE_POLICY_ACCEPT  0x02
#define UPDATE_POLICY_REJECT  0x03
#define UPDATE_POLICY_DATA    0x04
#define UPDATE_POLICY_FINISH  0x05

 

#endif

